/*********************************************************************
 * Clase de utilidad Vector Arrow. Dibuja una flecha
 * Programación Multimedia y Juegos
 * Autor: David Vallejo Fernández    david.vallejo@tegnix.com
 * Autor: Carlos González Morcillo   carlos.gonzalez@tegnix.com
 *
 * You can redistribute and/or modify this file under the terms of the
 * GNU General Public License ad published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * and later version. See <http://www.gnu.org/licenses/>.
 *
 * This file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.  
 *********************************************************************/

package graphics;

import aze.display.TileClip;
import aze.display.TileLayer;
import nme.geom.Point;

class VectorArrow {
  var _root:TileLayer;
  var _vSprite:Array<TileClip>;     // Sprites a dibujar...
  var _nPoints:Int;                 // Número de puntos a desplegar
  var _maxLength:Int;               // Longitud máxima del vector
  var _spx:Float; var _spy:Float;   // Posición inicial del vector
  var _fpx:Float; var _fpy:Float;   // Posición final del vector

  // Constructor ==================================================
  public function new(l: TileLayer, idBase:String, idDot:String, 
		      idArrow, px:Float, py:Float, nPoints:Int, 
		      length:Int):Void {

    _root = l; _nPoints = nPoints; _spx = px; _spy = py;
    _maxLength = length;  // Longitud máxima del vector
    _vSprite = new Array<TileClip>();

    var s:TileClip;
    // En este bucle, la primera posición añade el clip "idBase" 
    // El último es el "idArrow" (escalado al doble), 
    //   y los intermedios "idDot"
    for (i in 1..._nPoints+1) {
      if (i==1) s = new TileClip(idBase); 
      else if (i==nPoints) {s = new TileClip(idArrow); s.scale = 2;}
      else s = new TileClip(idDot);
      s.x = _spx; s.y = _spy; // Inicialmente todos en esta posición
      _vSprite.push(s);       // Añadimos al vector vSprite
      _root.addChild(s);
    }
  }

  // Clases auxiliares ============================================
  public function getVector():phx.Vector {
    var v = new Point(_fpx - _spx, _fpy - _spy);
    v.normalize(v.length * 0.25);
    return new phx.Vector(v.x, v.y);
  }

  public inline static function radToDeg(rad:Float):Float {
    return 180 / Math.PI * rad;
  }

  // Update =======================================================
  public function update():Void {
    var v = new Point(_fpx - _spx, _fpy - _spy); 
    v.normalize(v.length / _nPoints);
    for (i in 0..._nPoints) {         // Calculamos nueva posición
      _vSprite[i].x = _spx + v.x * i; // escalando el vector v
      _vSprite[i].y = _spy + v.y * i;
      if (i == _nPoints -1) {  // Actualizar rotación de la flecha
	v.normalize(1);
	var angle = Math.acos(v.x);
	if (v.y < 0) angle = 2*Math.PI - angle;
	_vSprite[i].rotation = angle;
      }
    }
  }

  public function setArrowPos(px:Float, py:Float):Void {
    var v = new Point(px - _spx, py - _spy);
    if (v.length > _maxLength) {
      v.normalize(_maxLength);
      _fpx = _spx + v.x; _fpy = _spy + v.y;
    }
    else { _fpx = px; _fpy = py; }
  }

  public function setBasePos(px:Float, py:Float):Void {
    _spx = px; _spy = py;
  }
}